chore: Add NetworkObject ownership docs and update related docs#3879
chore: Add NetworkObject ownership docs and update related docs#3879EmandM wants to merge 2 commits intodevelop-2.0.0from
Conversation
NoelStephensUnity
left a comment
There was a problem hiding this comment.
Made a few suggestions... otherwise it looks great (and was definitely needed).
| To see if the server owns a NetworkObject, you can check the [`NetworkObject.IsOwnedByServer`](https://docs.unity3d.com/Packages/com.unity.netcode.gameobjects@latest?subfolder=/api/Unity.Netcode.NetworkObject.IsOwnedByServer.html) or the [`NetworkBehaviour.IsOwnedByServer`](https://docs.unity3d.com/Packages/com.unity.netcode.gameobjects@latest?subfolder=/api/Unity.Netcode.NetworkBehaviour.IsOwnedByServer.html) property. | ||
|
|
||
| > [!NOTE] | ||
| > When you want a specific NetworkObject to keep existing after the owner leaves the session, you can set the `NetworkObject.DontDestroyWithOwner` property to `true`. This ensures that the owned NetworkObject isn't destroyed as the owner leaves. |
There was a problem hiding this comment.
Here are some suggested adjustments:
To assure a spawned NetworkObject persists after the owner leaves a session, set the NetworkObject.DontDestroyWithOwner property to true. This assures the client-owned NetworkObject doesn't get destroyed when the owning client leaves.
| ## Authority ownership | ||
|
|
||
| If you're creating a client-server game and you want a client to control more than one NetworkObject, or if you're creating a distributed authority game and the authority/current owner of the object would like to change ownership, use the following ownership methods. |
There was a problem hiding this comment.
Ownership vs authority
The client-server and distributed authority network topologies have slight differences when it comes to ownership and authority.
- Client-server: A client can own a spawned NetworkObject but the server always maintains spawn authority over the NetworkObject. Ownership only provides the owning client authority over NetworkVariables (with write permissions), any NetworkTransform configured for owner authority, and can be used to send an RPC that targets the owner.
- Distributed authority: If a client owns a NetworkObject it becomes the "over-all" authority of that NetworkObject. This means the owning client has spawn/de-spawn authority, write permissions to NetworkVariables (associated with the owned NetworkObject), the motion authority (if the NetworkObject has any NetworkTransforms), and the owning client can change the ownership permissions flags.
The following methods change their behavior based on the network topology being used:
There was a problem hiding this comment.
This, except one day Noel will learn that it's 'overall' not 'over-all'
| The default `NetworkObject.Spawn` method will set server-side ownership when using a client-server topology. When using a distributed authority topology, this method will set the client who calls the method as the owner. | ||
|
|
||
| ```csharp | ||
| GetComponent<NetworkObject>().Spawn(); | ||
| ``` |
There was a problem hiding this comment.
NetworkObject.Spawn
- Client-Server: The server defaults as the owner of this spawned object.
- Distributed authority: The client invoking this method becomes the owner of the spawned object.
com.unity.netcode.gameobjects/Documentation~/advanced-topics/networkobject-ownership.md
Outdated
Show resolved
Hide resolved
| ```csharp | ||
| GetComponent<NetworkObject>().ChangeOwnership(clientId); | ||
| ``` | ||
|
|
There was a problem hiding this comment.
NetworkObject.SpawnWithOwnership
- Client-Server: The client identifier passed in as a parameter defines who the owner will be.
- Distributed authority: It is not recommended to use this method when using distributed authority if there are initial settings you want applied when spawning the new instance. For this scenario, it is recommended to use
NetworkObject.Spawn, allow the settings to be applied locally, and then useNetworkObject.ChangeOwnership.
There was a problem hiding this comment.
I moved SpawnWithOwnership to the bottom of the page. That way ChangeOwnership has a higher prominence than SpawnWithOwnership, hopefully leading to fewer SpawnAuthority issues.
| internal class MyRequestableBehaviour : NetworkBehaviour | ||
| { | ||
| public override void OnNetworkSpawn() | ||
| { | ||
| NetworkObject.OnOwnershipRequestResponse = OnOwnershipRequestResponse; | ||
| base.OnNetworkSpawn(); | ||
| } | ||
|
|
||
| private void OnOwnershipRequestResponse(NetworkObject.OwnershipRequestResponseStatus ownershipRequestResponseStatus) | ||
| { | ||
| // Called when the requesting client has gotten a response to their request | ||
| } | ||
|
|
||
| public override void OnNetworkDespawn() | ||
| { | ||
| NetworkObject.OnOwnershipRequestResponse = null; | ||
| base.OnNetworkDespawn(); | ||
| } | ||
| } |
There was a problem hiding this comment.
///
/// When a NetworkObject's permissions includes the
/// flag.
///
public class RequestableOwnershipBehaviour : NetworkBehaviour
{
public override void OnNetworkSpawn()
{
NetworkObject.OnOwnershipRequestResponse += OnOwnershipRequestResponse;
base.OnNetworkSpawn();
}
private void OnOwnershipRequestResponse(NetworkObject.OwnershipRequestResponseStatus ownershipRequestResponseStatus)
{
switch (ownershipRequestResponseStatus)
{
case NetworkObject.OwnershipRequestResponseStatus.Approved:
{
// OnOwnershipChanged and OnGainedOwnership is invoked on the client requesting side.
// OnOwnershipChanged and OnLostOwnership is invoked on the previous owning client side.
break;
}
case NetworkObject.OwnershipRequestResponseStatus.RequestInProgress:
{
// Another client already has a request pending.
break;
}
case NetworkObject.OwnershipRequestResponseStatus.CannotRequest:
{
// Cannot request means RequestRequired is no longer a permission of this NetworkObject.
// The owning client changed while the request was being sent.
break;
}
case NetworkObject.OwnershipRequestResponseStatus.Denied:
{
// The owning client denied the request.
break;
}
case NetworkObject.OwnershipRequestResponseStatus.Locked:
{
// Ownership has been locked by the owning client.
break;
}
}
}
public override void OnNetworkDespawn()
{
NetworkObject.OnOwnershipRequestResponse -= OnOwnershipRequestResponse;
base.OnNetworkDespawn();
}
}
| To spawn a `NetworkObject` that is [owned](../../terms-concepts/ownership.md) by a different game client than the one doing the spawning, use the following: | ||
|
|
||
| ```csharp | ||
| GetComponent<NetworkObject>().SpawnWithOwnership(clientId); |
There was a problem hiding this comment.
NetworkObject.SpawnWithOwnership(clientId);
| ### Who can parent NetworkObjects | ||
|
|
||
| Similar to [Ownership](../basics/networkobject#ownership), only the server (or host) can control NetworkObject component parenting. | ||
| By default, only the [authority](../terms-concepts/authority.md) of an object can change the parenting of the object. This means in a client-server game, only the server (or host) can control NetworkObject component parenting. In a distributed authority game the owner of the object can always parent the object. |
There was a problem hiding this comment.
owner of the object can always parent the object under any other spawned NetworkObject (owned or not).
| In [client-server](client-server.md), ownership behaves as a subset of [authority](./authority.md). The owner of an object can control some aspects of that object, while the authority controls and synchronizes others. | ||
|
|
||
| In a distributed authority setting, authority over NetworkObjects isn't bound to a single server, but distributed across clients depending on a NetworkObject's [ownership permission settings](#ownership-permission-settings-distributed-authority-only). NetworkObjects with the distributable permission set are automatically distributed amongst clients as they connect and disconnect. | ||
| Ownership provides client-side reactivity. By giving individual clients ownership over objects that are important for their gameplay, clients can locally control some parts of their game. For example, this allows clients to avoid lag in their player controller, while leaving the server as the final game authority. |
There was a problem hiding this comment.
Just remove the space:
Ownership provides client-side reactivity. By giving individual clients ownership
|
|
||
|  | ||
| **This default behaviour can be changed using the [NetworkVariableWritePermission.Owner](../basics/networkvariable.md#write-permissions) | ||
| ***This default behaviour can be changed by setting [NetworkObject.AllowOwnerToParent](../advanced-topics/networkobject-parenting.md#who-can-parent-networkobjects) |
There was a problem hiding this comment.
|-----------------------------------|----------|-------|
|Spawn/Despawn objects* |Yes |No |
|Change Ownership |Yes |No |
|Move transform** |No |Yes|
|Update NetworkVariables*** |Yes |No |
|Synchronize late joining clients |Yes |No |
|Update object parenting**** |Yes |No |
*The authority when using client-server will always be the server.
**Only when a NetworkTransform's authority mode is set to owner.
***This default behaviour can be changed using the NetworkVariableWritePermission.Owner
****This default behaviour can be changed by setting NetworkObject.AllowOwnerToParent
There was a problem hiding this comment.
This, but 'behavior' rather than 'behaviour'
jabbacakes
left a comment
There was a problem hiding this comment.
Lots of suggestions here, but it's a lot of new doc 😅 Nothing major, just a lot of wording/style/consistency tweaks.
There are a lot of changes here and it's getting a bit hard to see the wood for the trees, but we'll be rereviewing this content as part of the centralisation efforts so I think it's all good for now.
| * [Authority](authority.md) | ||
| * [Client-server](client-server.md) | ||
| * [Distributed authority](distributed-authority.md) | ||
| * [Controlling NetworkObject ownership](../advanced-topics/networkobject-ownership.md) |
There was a problem hiding this comment.
| * [Controlling NetworkObject ownership](../advanced-topics/networkobject-ownership.md) | |
| * [NetworkObject ownership](../advanced-topics/networkobject-ownership.md) |
| ## Overview | ||
|
|
||
| If you aren't completely familiar with transform parenting in Unity, then it's highly recommended to [review over the existing Unity documentation](https://docs.unity3d.com/Manual/class-Transform.html) before reading further to properly synchronize all connected clients with any change in a GameObject component's transform parented status, Netcode for GameObjects requires that the parent and child GameObject components have NetworkObject components attached to them. | ||
| If you aren't completely familiar with transform parenting in Unity, then it's highly recommended to [review over the existing Unity documentation](https://docs.unity3d.com/Manual/class-Transform.html) before reading further. To properly synchronize all connected clients with any change in a GameObject component's transform parented status, Netcode for GameObjects requires that the parent and child GameObject components have NetworkObject components attached to them. Otherwise, you can use the [AttachableBehaviour](../components/helper/attachablebehaviour.md) and [AttachableNode](../components/helper/attachablenode.md) helper components to synchronize other types of parenting. |
There was a problem hiding this comment.
| If you aren't completely familiar with transform parenting in Unity, then it's highly recommended to [review over the existing Unity documentation](https://docs.unity3d.com/Manual/class-Transform.html) before reading further. To properly synchronize all connected clients with any change in a GameObject component's transform parented status, Netcode for GameObjects requires that the parent and child GameObject components have NetworkObject components attached to them. Otherwise, you can use the [AttachableBehaviour](../components/helper/attachablebehaviour.md) and [AttachableNode](../components/helper/attachablenode.md) helper components to synchronize other types of parenting. | |
| If you aren't familiar with transform parenting in Unity, then it's recommended that you [review the existing Unity documentation](https://docs.unity3d.com/Manual/class-Transform.html) before reading further. To properly synchronize all connected clients with any change in a GameObject component's transform parented status, Netcode for GameObjects requires that the parent and child GameObject components have NetworkObject components attached to them. Otherwise, you can use the [AttachableBehaviour](../components/helper/attachablebehaviour.md) and [AttachableNode](../components/helper/attachablenode.md) helper components to synchronize other types of parenting. |
| - It's recommended to always use the `NetworkObject.TrySetParent` method when parenting if you plan on changing the `WorldPositionStays` default value. | ||
| - Likewise, it's also recommended to use the `NetworkObject.TryRemoveParent` method to remove a parent from a child. | ||
| - When a server parents a spawned NetworkObject component under another spawned NetworkObject component during a Netcode game session this parent child relationship replicates across the network to all connected and future late joining clients. | ||
| - When an [authority](../terms-concepts/authority.md) parents a spawned NetworkObject component under another spawned NetworkObject component during a Netcode game session this parent child relationship replicates across the network to all connected and future late joining clients. |
There was a problem hiding this comment.
| - When an [authority](../terms-concepts/authority.md) parents a spawned NetworkObject component under another spawned NetworkObject component during a Netcode game session this parent child relationship replicates across the network to all connected and future late joining clients. | |
| - When an [authority](../terms-concepts/authority.md) parents a spawned NetworkObject component under another spawned NetworkObject component during a Netcode game session, this parent-child relationship replicates across the network to all connected and future late-joining clients. |
| ### Who can parent NetworkObjects | ||
|
|
||
| Similar to [Ownership](../basics/networkobject#ownership), only the server (or host) can control NetworkObject component parenting. | ||
| By default, only the [authority](../terms-concepts/authority.md) of an object can change the parenting of the object. This means in a client-server game, only the server (or host) can control NetworkObject component parenting. In a distributed authority game the owner of the object can always parent the object. |
There was a problem hiding this comment.
| By default, only the [authority](../terms-concepts/authority.md) of an object can change the parenting of the object. This means in a client-server game, only the server (or host) can control NetworkObject component parenting. In a distributed authority game the owner of the object can always parent the object. | |
| By default, only the [authority](../terms-concepts/authority.md) of a NetworkObject can change the parenting of that NetworkObject. | |
| - In a client-server game, only the server (or host) can control NetworkObject parenting. | |
| - In a distributed authority game, the owner of the NetworkObject can always parent the NetworkObject. |
| Similar to [Ownership](../basics/networkobject#ownership), only the server (or host) can control NetworkObject component parenting. | ||
| By default, only the [authority](../terms-concepts/authority.md) of an object can change the parenting of the object. This means in a client-server game, only the server (or host) can control NetworkObject component parenting. In a distributed authority game the owner of the object can always parent the object. | ||
|
|
||
| To allow the [owner](../terms-concepts/ownership.md) to parent their owned object in a client-server game, use the [`NetworkObject.AllowOwnerToParent`](https://docs.unity3d.com/Packages/com.unity.netcode.gameobjects@latest?subfolder=/api/Unity.Netcode.NetworkObject.html#Unity_Netcode_NetworkObject_AllowOwnerToParent) property. |
There was a problem hiding this comment.
| To allow the [owner](../terms-concepts/ownership.md) to parent their owned object in a client-server game, use the [`NetworkObject.AllowOwnerToParent`](https://docs.unity3d.com/Packages/com.unity.netcode.gameobjects@latest?subfolder=/api/Unity.Netcode.NetworkObject.html#Unity_Netcode_NetworkObject_AllowOwnerToParent) property. | |
| To allow the [owner](../terms-concepts/ownership.md) to parent their owned NetworkObject in a client-server game, use the [`NetworkObject.AllowOwnerToParent`](https://docs.unity3d.com/Packages/com.unity.netcode.gameobjects@latest?subfolder=/api/Unity.Netcode.NetworkObject.html#Unity_Netcode_NetworkObject_AllowOwnerToParent) property. |
| |Move transform |No |**Yes**| | ||
| |Update NetworkVariables** |**Yes** |No | | ||
| |Synchronize late joining clients|**Yes** |No | | ||
| |Update object parenting*** |**Yes** |No | |
There was a problem hiding this comment.
| |Update object parenting*** |**Yes** |No | | |
| |Update NetworkObject parenting*** |**Yes** |No | |
|
|
||
|  | ||
| **This default behaviour can be changed using the [NetworkVariableWritePermission.Owner](../basics/networkvariable.md#write-permissions) | ||
| ***This default behaviour can be changed by setting [NetworkObject.AllowOwnerToParent](../advanced-topics/networkobject-parenting.md#who-can-parent-networkobjects) |
There was a problem hiding this comment.
This, but 'behavior' rather than 'behaviour'
| ## Ownership in distributed authority | ||
|
|
||
| You can also use `NetworkObject.SetOwnershipLock` to lock and unlock the permission settings of a NetworkObject for a period of time, preventing ownership changes on a temporary basis. | ||
| In [distributed authority](./distributed-authority.md) the owner of an object is always the authority of that object. In this way, ownership comes before authority. Authority can be transferred between clients via changing and requesting ownership. |
There was a problem hiding this comment.
| In [distributed authority](./distributed-authority.md) the owner of an object is always the authority of that object. In this way, ownership comes before authority. Authority can be transferred between clients via changing and requesting ownership. | |
| In [distributed authority](./distributed-authority.md) the owner of a NetworkObject is always the authority of that NetworkObject. In this way, ownership comes before authority. Authority can be transferred between clients via changing and requesting ownership. |
|
|
||
| > [!NOTE] | ||
| > The ownership permissions are only visible when you have the Multiplayer Services SDK package installed and you're inspecting a NetworkObject within the Editor. Ownership permissions have no impact when using a client-server network topology, because the server always has authority. | ||
| When building your game you can use [ownership permissions](../advanced-topics/networkobject-ownership.md#ownership-permissions-settings) to control how and when ownership of objects can be transferred between clients. |
There was a problem hiding this comment.
| When building your game you can use [ownership permissions](../advanced-topics/networkobject-ownership.md#ownership-permissions-settings) to control how and when ownership of objects can be transferred between clients. | |
| When building your game, you can use [ownership permissions](../advanced-topics/networkobject-ownership.md#ownership-permissions-settings) to control how and when ownership of o NetworkObjects can be transferred between clients. |
| When building your game you can use [ownership permissions](../advanced-topics/networkobject-ownership.md#ownership-permissions-settings) to control how and when ownership of objects can be transferred between clients. | ||
|
|
||
| #### Request ownership | ||
| Objects with the `OwnershipStatus.Distributable` permission will have their ownership automatically distributed between all connected game clients whenever a new client joins or an existing client leaves. This is the key mechanism in how the game simulation is distributed between clients in a distributed authority session. |
There was a problem hiding this comment.
| Objects with the `OwnershipStatus.Distributable` permission will have their ownership automatically distributed between all connected game clients whenever a new client joins or an existing client leaves. This is the key mechanism in how the game simulation is distributed between clients in a distributed authority session. | |
| NetworkObjects with the `OwnershipStatus.Distributable` permission have their ownership automatically distributed between all connected game clients whenever a new client joins or an existing client leaves. This is the key mechanism in how the game simulation is distributed between clients in a distributed authority session. |
jabbacakes
left a comment
There was a problem hiding this comment.
Lots of suggestions here, but it's a lot of new doc 😅 Nothing major, just a lot of wording/style/consistency tweaks.
There are a lot of changes here and it's getting a bit hard to see the wood for the trees, but we'll be rereviewing this content as part of the centralisation efforts so I think it's all good for now.
Purpose of this PR
At long last.... Ownership docs!
Jira ticket
Link to related jira ticket (Use the smart commits). Short version (e.g. MTT-123) also works and gets auto-linked
Changelog
Documentation
Testing & QA (How your changes can be verified during release Playtest)
Functional Testing
Manual testing :
Manual testing doneAutomated tests:
Covered by existing automated testsCovered by new automated testsDoes the change require QA team to:
Review automated tests?Execute manual tests?Provide feedback about the PR?If any boxes above are checked the QA team will be automatically added as a PR reviewer.
Backports